package luke.audio.analyzer;


import java.io.*;

import luke.audio.processor.AudioTranscoder;

/**
 * 通用音频解码器
 * 支持多种音频格式的解码，包括MP3、WAV、FLAC等
 */
public class UniversalAudioDecoder {


    public UniversalAudioDecoder() {

    }

    /**
     * 解码音频文件为PCM数据
     *
     * @param audioFile 音频文件
     * @return 音频数据容器对象
     * @throws Exception 解码过程中可能出现的异常
     */
    public AudioData decodeAudioFile(File audioFile) throws Exception {
        // 直接将文件转换为PCM字节数据（使用静态方法）
        byte[] pcmData = AudioTranscoder.convertFileToPCM(audioFile);
        
        // 获取统一的音频参数（使用静态方法）
        int sampleRate = AudioTranscoder.getSampleRate();
        int channels = AudioTranscoder.getChannels();
        
        // 直接将PCM数据转换为float数组
        return processPCMData(pcmData, sampleRate, channels);
    }

    /**
     * 直接处理PCM数据为AudioData对象
     *
     * @param pcmData PCM音频数据
     * @param sampleRate 采样率
     * @param channels 声道数
     * @return 音频数据容器对象
     */
    private static AudioData processPCMData(byte[] pcmData, int sampleRate, int channels) {
        if (pcmData == null || pcmData.length == 0) {
            return new AudioData(new float[0], sampleRate, channels);
        }

        int sampleSize = 2; // 16-bit = 2 bytes
        int numSamples = pcmData.length / sampleSize;
        float[] audioData = new float[numSamples];

        // 转换为归一化的浮点数组
        for (int i = 0; i < numSamples; i++) {
            int byteIndex = i * sampleSize;
            int sample = (pcmData[byteIndex] & 0xFF) | (pcmData[byteIndex + 1] << 8);
            if (sample > 32767) sample -= 65536; // 处理有符号整数
            audioData[i] = sample / 32768.0f;
        }

        return new AudioData(audioData, sampleRate, channels);
    }

    /**
     * 音频数据容器类
     * 用于存储解码后的音频数据
     */
    public static class AudioData {
        public final float[] data;
        public final int sampleRate;
        public final int channels;

        public AudioData(float[] data, int sampleRate, int channels) {
            this.data = data;
            this.sampleRate = sampleRate;
            this.channels = channels;
        }
    }
}